﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.Windows.Forms;
using DirectX.Capture;

namespace WebcamGrabber
{
   public class WebcamClass
   {
      private readonly Size CapSize = new Size(320, 240);
      private Filters filters;
      private readonly AutoResetEvent ManReset;
      private readonly Panel videoPanel;
      public Bitmap Bitmap{ get; set;}
      private Capture capture;

      private bool Initialized;

      public WebcamClass(Panel VideoPanel,Size CaptureSize)
      :this()
      {
         videoPanel = VideoPanel;
         videoPanel.Size = CaptureSize;
         
      }
      public WebcamClass(Size CaptureSize)
         : this()
      {
         CapSize = CaptureSize;
         videoPanel.Size = CapSize;
      }

      public WebcamClass()
      {
         videoPanel = new Panel();

         ManReset = new AutoResetEvent(true);
         videoPanel.Size = CapSize;
      }

      public Panel VideoPanel
      {
         get { return videoPanel; }
      }

      public event Capture.HeFrame FrameCaptured;

      public bool Initialize()
      {
         if (Initialized)
            return true;
         try
         {

            filters = new Filters();
            if (filters.VideoInputDevices.Count <= 0)
               throw new NullReferenceException("Keine Webcam gefunden");
            capture = new Capture(filters.VideoInputDevices[0], null);
            capture.FrameEvent2 += capture_FrameEvent2;
            capture.FrameSize = CapSize;
            capture.FrameRate = 15.0;
            capture.RunVideo(videoPanel);
            Initialized = true;
            getImage();
         }
         catch (Exception)
         {
            return false;
         }
         return true;
      }
      public bool ReInitialize()
      {
         if(!Initialized)
         {
            return Initialize();
         }
         try
         {

            capture.Dispose();
            if (filters.VideoInputDevices.Count <= 0)
               throw new NullReferenceException("Keine Webcam gefunden");
            capture = new Capture(filters.VideoInputDevices[0], null);
            capture.FrameEvent2 += capture_FrameEvent2;
            capture.FrameSize = CapSize;
            capture.FrameRate = 5.0;
            capture.RunVideo(videoPanel);
            Initialized = true;
            getImage();
            return true;
         }
         catch
         {
            return false;
         }
      }
      private void capture_FrameEvent2(Bitmap BM)
      {
         Bitmap = (Bitmap)BM.Clone();
         Thread.Sleep(10);
            ManReset.Set();
         //if (FrameCaptured != null)
         //   FrameCaptured(BM);
      }

      public int getByteSize()
      {
         if (Bitmap == null)
            return 0;
         BitmapData bmData = Bitmap.LockBits(new Rectangle(new Point(0, 0), Bitmap.Size), ImageLockMode.ReadOnly,
                                          Bitmap.PixelFormat);
         int Sze = Bitmap.Height*bmData.Stride;
         Bitmap.UnlockBits(bmData);
         return Sze;
      }

      public bool getImage()
      {
         if(!Initialize())
            return false;

         capture.GrapImg();
         return true;
         }

      public PropertyPageCollection PropPages()
      {
         try
         {
            return capture.PropertyPages;
         }
         catch
         {}
         return null;
      }
   }
}